﻿using System;
using System.Configuration;
using System.Diagnostics;
using System.Xml;

namespace Expect.Core.Config
{
    
    /// <summary>
    /// Configuration section for expect
    /// </summary>
    public class ExpectConfigurationSection : ConfigurationSection
    {
        /// <summary>
        /// Configuration elements for code generation
        /// </summary>
        [ConfigurationProperty("codegen", IsRequired = false)]
        public CodeGenElement CodeGen
        {
            get { return (CodeGenElement)this["codegen"]; }
            set { this["codegen"] = value; }
        }

        /// <summary>
        /// Configuration elements for code generation
        /// </summary>
        [ConfigurationProperty("report", IsRequired = false)]
        public ReportElement Report
        {
            get { return (ReportElement)this["report"]; }
            set { this["report"] = value; }
        }

        /// <summary>
        /// Read configuration from an app.config file content
        /// </summary>
        /// <param name="filename">app.config file content</param>
        /// <returns>configuration section</returns>
        public static ExpectConfigurationSection ReadFromFile(string filename)
        {
            if (string.IsNullOrEmpty(filename)) return null;

            XmlDocument configDocument;
            try
            {
                configDocument = new XmlDocument();
                configDocument.Load(filename);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex, "Config load error");
                return null;
            }

            return ReadConfig(configDocument);
        }

        /// <summary>
        /// Read configuration from an app.config file content
        /// </summary>
        /// <param name="file">app.config file content</param>
        /// <returns>configuration section</returns>
        public static ExpectConfigurationSection ReadFromContent(string file)
        {
            if (string.IsNullOrEmpty(file)) return null;

            XmlDocument configDocument;
            try
            {
                configDocument = new XmlDocument();
                configDocument.LoadXml(file);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex, "Config load error");
                return null;
            }

            return ReadConfig(configDocument);
        }

        private static ExpectConfigurationSection ReadConfig(XmlDocument configDocument)
        {
            var specFlowNode = configDocument.SelectSingleNode("/configuration/expect");
            if (specFlowNode == null)
                return null;

            ExpectConfigurationSection section = new ExpectConfigurationSection();
            section.Init();
            section.Reset(null);
            using (var reader = new XmlNodeReader(specFlowNode))
            {
                section.DeserializeSection(reader);
            }
            section.ResetModified();
            return section;
        }
    }
}
